//引入Q模块
let Q = require('q');
//引入公共函数
let util = require('../../util');
//引入https用于发起https请求
let https = require('https');
//存放商户mongodb数据库操作对象
let db;

//storePay接口入口文件
let index = function(getData, postData, config, _redis, _db) {
	let deferred = Q.defer();
	//判断是否存在用户ID以及购买的菜品数据（菜品ID和菜品数量）
	if(postData.storeId && postData.tableNum && postData.openId && postData.payGoods && postData.payGoods[0] && postData.payGoods[0].foodId && postData.payGoods[0].count && postData.attachGoods) {
		//赋值数据库实例
		db = _db;
		getStoreData().then(function(storeData) {
			if(!storeData.storeName) {
				//无法识别支付商户
				deferred.reject('-0093');
				return deferred.promise;
			}
			//获得调用支付的用户的ID
			let userId = postData.openId;
			//获得菜品数据
			let payGoods = postData.payGoods;
			//获得附加物品数据
			let attachGoods = postData.attachGoods;

			let payGoodsOrderData = [];

			let attachGoodsData = [];
			//调用根据菜品ID列表获取购买的菜品信息列表
			getPayGoodsData(payGoods).then(function(_payGoodsOrderData) {
				payGoodsOrderData = _payGoodsOrderData;
				return getAttachGoodsData(attachGoods);
			}, function(errCode) {
				//获取购买的菜品数据失败
				deferred.reject(errCode);
			}).then(function(_attachGoodsData) {
				console.log('附加物品列表数据：', _attachGoodsData);
				attachGoodsData = _attachGoodsData;
				//调用创建订单函数
				return createOrder(payGoods, payGoodsOrderData, attachGoodsData);
			}, function() {
				//获取购买的附加物品数据失败
				deferred.reject('-0118');
			}).then(function(orderData) {
				util.createRandomStr(24).then(function(orderId) {
					//在订单号前面加上商户Id用于支付通知时得到订单号
					orderId = postData.storeId + '-' + orderId;
					console.log(orderId);
					//调用微信统一下单接口函数
					wxPlaceOrder(orderId, orderData, storeData, userId, postData.clientIP, config).then(function(wxPlaceOrderInterfaceData) {
						console.log(wxPlaceOrderInterfaceData);
						// for(let goodsIndex in orderData) {
						// 	if(orderData[goodsIndex].foodPrice) {
						// 		orderData[goodsIndex].foodPrice = orderData[goodsIndex].foodPrice * 0.02;
						// 	}
						// 	else if(orderData[goodsIndex].goodsPrice) {
						// 		orderData[goodsIndex].goodsPrice = orderData[goodsIndex].goodsPrice * 0.02;
						// 	}
						// }
						//新增订单到数据库
						db.insert('storeOrder', {
							//商户ID
							storeId: storeData.storeId,
							//商户名称
							storeName: storeData.storeName,
							//创建订单的ID
							orderId: orderId,
							//创建订单的用户ID
							userId: userId,
							//创建订单的桌号
							tableNum: postData.tableNum,
							//统一下单的订单号
							prepayId: wxPlaceOrderInterfaceData.prepay_id,
							//创建订单的菜品数据
							goodsList: orderData,
							//创建订单的时间戳
							timestamp: parseInt(Date.now() / 1000),
							//设置支付方式为微信付款
							payMode: 'wxPay',
							//订单是否已结束
							orderDone: false,
							//是否已经完成支付操作
							userPayed: false,
							//商户是否已收到转账
							storeReceiveMoney: false,
							//提现ID
							withdrawCashId: ''
						}).then(function() {
							console.log('新增订单成功');
							util.createRandomStr(32).then(function(nonceStr) {
								var paySign = '';
								var payData = {
									//小程序ID
									appId: config.clientAppId,
									//当前时间戳（秒）
									timeStamp: '' + parseInt(Date.now() / 1000),
									//随机字符串
									nonceStr: nonceStr,
									//放入预支付订单ID
									package: 'prepay_id=' + wxPlaceOrderInterfaceData.prepay_id,
									//签名算法为MD5
									signType: 'MD5'
								}
								//取出所有支付数据Key
								var dataKeys = Object.keys(payData);
								//对对象key进行字典排序
								dataKeys = dataKeys.sort();
								//遍历对象key数组将对应数据连接到签名字符串
								for(var index in dataKeys) {
									//连接签名字符串
									paySign += dataKeys[index] + '=' + payData[dataKeys[index]] + '&';
									if(index == dataKeys.length - 1) {
										//连接上支付key
										paySign += 'key=' + config.payKey;
										console.log(paySign);
										//进行md5加密
										util.md5(paySign).then(function(signStr) {
											paySign = signStr.toUpperCase();
											console.log('生成签名：' + paySign);
											//添加订单成功返回预支付数据
											deferred.resolve({
												//支付的订单
												orderId: orderId,
												//支付时的时间戳
												timeStamp: payData.timeStamp,
												//随机字符串
												nonceStr: payData.nonceStr,
												//存放prepay_id
												package: payData.package,
												//签名算法名称
												signType: payData.signType,
												//签名字符串
												paySign: paySign
											});
										}, function() {
											//md5加密失败
											deferred.reject('-0086');
										});
									}
								}
							}, function() {
								//生成随机字符串失败
								deferred.reject('-0069');
							});
						}, function() {
							//新增订单失败
							deferred.reject('-0083');
						});
					}, function(errCode) {
						deferred.reject(errCode);
					});
				}, function() {
					//创建订单号失败
					deferred.reject('-0085');
				});
			}, function(errCode) {
				//生成菜品订单失败
				deferred.reject(errCode);
			});
		}, function() {
			//查询商户信息失败
			deferred.reject('-0040');
		});
	}
	else {
		//没有选择任何菜品
		deferred.reject('-0082');
	}
	return deferred.promise;
}

//获取商户数据函数
var getStoreData = function() {
	var deferred = Q.defer();
	db.select('storeInfo', {}).then(function(storeInfo) {
		var storeData = {};
		var storeInfoKey = '';
		if(storeInfo.length == 0) {
			deferred.resolve(storeData);
		}
		else {
			for(var infoIndex in storeInfo) {
				for(var storeInfoKey in storeInfo[infoIndex]) {
					if(storeInfoKey != '_id') {
						storeData[storeInfoKey] = storeInfo[infoIndex][storeInfoKey];
						if(infoIndex == storeInfo.length - 1) {	
							console.log(storeData);
							deferred.resolve(storeData);
						}
					}
				}
			}
		}
	}, function() {
		deferred.reject();
	});
	return deferred.promise;	
}

//获取支付的物品数据
var getPayGoodsData = function(payGoods) {
	var deferred = Q.defer();
	//预定义一个进行or查询的数组变量	
	var payGoodsList = [];
	//遍历支付的物品列表
	for(var goodsIndex in payGoods) {
		//往正式支付的物品列表中添加菜品ID
		payGoodsList.push({
			foodId: payGoods[goodsIndex].foodId
		});
		//判断遍历是否完成
		if(goodsIndex == payGoods.length - 1) {
			db.select('foodMenu', {
				$or: payGoodsList
			}).then(function(payGoodsData) {
				deferred.resolve(payGoodsData);
			}, function() {
				deferred.reject('-0063');
			});
		}
	}
	return deferred.promise;
}

let getAttachGoodsData = function(attachGoods) {
	let deferred = Q.defer();
	//预定义一个进行or查询的数组变量	
	let attachGoodsList = [];

	if(attachGoods.length == 0) {
		deferred.resolve([]);
	}

	//遍历支付的附加物品列表
	for(var goodsIndex in attachGoods) {
		//往正式支付的物品列表中添加菜品ID
		attachGoodsList.push({
			goodsId: attachGoods[goodsIndex].goodsId
		});
		//判断遍历是否完成
		if(goodsIndex == attachGoods.length - 1) {
			db.select('attachGoods', {
				$or: attachGoodsList
			}).then(function(attachGoodsData) {
				deferred.resolve(attachGoodsData);
			}, function() {
				deferred.reject('-0063');
			});
		}
	}
	return deferred.promise;
}

//创建订单函数
var createOrder = function(payGoodsList, payGoodsOrderList, attachGoodsData) {
	var deferred = Q.defer();
	console.log('处理附加物品', attachGoodsData);
	//存放错误的菜品列表
	var errorGoodsOrder = [];
	var orderList = [];
	//判断提交的订单信息中是否包含了不存在的菜品
	if(payGoodsList.length != payGoodsOrderList.length) {
		//用于判断是否找到对应的支付物品
		var goodsFound = false;
		//遍历检查是哪个菜品出现问题
		for(var goodsIndex in payGoodsList) {
			//如果只有一个菜品，那么直接将这个物品推入错误列表
			if(payGoodsOrderList.length == 1) {
				errorGoodsOrder.push(payGoodsList[goodsIndex]);
			}
			else {
				for(var goodsOrderIndex in payGoodsOrderList) {
					if(payGoodsOrderList[goodsOrderIndex].foodId == payGoodsList[goodsIndex].foodId) {
						//设置找到了对应菜品
						goodsFound = true;
					}
					else if(goodsOrderIndex == payGoodsOrderList.length - 1 && goodsFound == false) {
						//出错的菜品
						errorGoodsOrder.push(payGoodsList[goodsIndex].foodId);
					}
				}
				//重置
				goodsFound = false;
			}
			//判断是否遍历完毕
			if(goodsIndex == payGoodsList.length - 1) {
				//如果不存在任何一个错误的菜品则返回错误
				if(errorGoodsOrder.length == 0) {
					//订单中可能存在重复菜品ID
					deferred.reject('-0084');
				}
				else {
					//返回菜品列表异常
					deferred.resolve({
						status: -1,
						data: errorGoodsOrder
					});
				}
			}
		}
		
	}
	else {
		//遍历支付的菜品列表与数据库的菜品列表判断是否下架或缺货
		for(var goodsIndex in payGoodsList) {
			for(var goodsOrderIndex in payGoodsOrderList) {
				if(payGoodsList[goodsIndex].foodId == payGoodsOrderList[goodsOrderIndex].foodId) {
					if(payGoodsOrderList[goodsOrderIndex].foodStatus == 'pulled' || (payGoodsOrderList[goodsOrderIndex].foodStock != -1 && payGoodsList[goodsIndex].count >= payGoodsOrderList[goodsOrderIndex].foodStock)) {
						errorGoodsOrder.push(payGoodsList[goodsIndex].foodId);
					}
					else {
						//往订单列表添加订单
						orderList.push({
							//菜品ID
							foodId: payGoodsOrderList[goodsIndex].foodId,
							//菜品名称
							foodName: payGoodsOrderList[goodsIndex].foodName,
							//菜品价格
							foodPrice: payGoodsOrderList[goodsIndex].foodPrice,
							//点选的菜品数量
							count: payGoodsList[goodsIndex].count
						});
					}
				}
			}
			//判断是否遍历到了最后一个
			if(goodsIndex == payGoodsList.length - 1) {
				if(attachGoodsData.length == 0) {
					//如果有菜品下架或缺货则返回-2
					if(errorGoodsOrder.length > 0) {
						deferred.resolve({
							status: -2,
							data: errorGoodsOrder
						});
					}
					else {
						//订单正确返回需要支付的列表
						deferred.resolve(orderList);
					}
				}
				for(let attachGoodsIndex in attachGoodsData) {
					orderList.push({
						//附加物品ID
						goodsId: attachGoodsData[attachGoodsIndex].goodsId,
						//附加物品名称
						goodsName: attachGoodsData[attachGoodsIndex].goodsName,
						//附加物品单价
						goodsPrice: attachGoodsData[attachGoodsIndex].goodsPrice,
						//附加物品数量
						goodsCount: attachGoodsData[attachGoodsIndex].goodsCount
					});
					if(attachGoodsIndex == attachGoodsData.length - 1) {
						//如果有菜品下架或缺货则返回-2
						if(errorGoodsOrder.length > 0) {
							deferred.resolve({
								status: -2,
								data: errorGoodsOrder
							});
						}
						else {
							//订单正确返回需要支付的列表
							deferred.resolve(orderList);
						}
					}
				}
			}
		}
	}
	return deferred.promise;
}

//调用微信统一下单接口函数
var wxPlaceOrder = function(orderId, orderData, storeData, userId, clientIP, config) {
	var deferred = Q.defer();
	//生成随机的32位字符串
	util.createRandomStr(32).then(function(nonceStr) {
		//取得当前的时间对象
		var date = new Date();
		//取得当前的时间戳
		var timestamp = date.getTime();
		//存放下单时间时间
		var orderStartTime = '' + date.getFullYear() + 
							(date.getMonth() < 10 ? '0' + (date.getMonth() + 1) : (date.getMonth() + 1)) + 
							(date.getDate() < 10 ? '0' + (date.getDate()) : (date.getDate())) + 
							(date.getHours() < 10 ? '0' + (date.getHours()) : (date.getHours())) + 
							(date.getMinutes() < 10 ? '0' + (date.getMinutes()) : (date.getMinutes())) + 
							(date.getSeconds() < 10 ? '0' + (date.getSeconds()) : (date.getSeconds()));
		//将当前的时间戳加上设定的对应秒数并更新时间对象为未来的时间
		date = new Date(timestamp + (config.orderExpire * 1000));
		//获取未来的时间作为订单结束的时间
		var orderEndTime = '' + date.getFullYear() + 
							(date.getMonth() < 10 ? '0' + (date.getMonth() + 1) : (date.getMonth() + 1)) + 
							(date.getDate() < 10 ? '0' + (date.getDate()) : (date.getDate())) + 
							(date.getHours() < 10 ? '0' + (date.getHours()) : (date.getHours())) + 
							(date.getMinutes() < 10 ? '0' + (date.getMinutes()) : (date.getMinutes())) + 
							(date.getSeconds() < 10 ? '0' + (date.getSeconds()) : (date.getSeconds()));
		console.log('物品数据', orderData);
		var goodsDetail = [];
		var goodsTotalPrice = 0;
		for(var index in orderData) {
			goodsDetail.push({
				goods_id: orderData[index].foodId || orderData[index].goodsId,
				//wxpay_goods_id: 10001
				goods_name: orderData[index].foodName || orderData[index].goodsName,
				quantity: orderData[index].count || orderData[index].goodsCount,
				//物品价格（分为单位）
				price: orderData[index].foodPrice || orderData[index].goodsPrice,
				//goods_category: 123456,
				//body: ''
			});
			if(orderData[index].foodId) {
				orderData[index].serving = false;
			}
			let price = orderData[index].foodPrice || orderData[index].goodsPrice;
			let count = orderData[index].count || orderData[index].goodsCount;
			//统计进总价中
			goodsTotalPrice += parseInt(price) * parseInt(count);
			console.log(goodsTotalPrice);
			if(index == orderData.length - 1) {
				console.log('订单详情', goodsDetail);
				//用于调用微信统一下单接口的数据
				var requestOrderData = {
					//商户ID
					appid: config.clientAppId,
					//订单名称
					attach: storeData.storeName,
					//商户号
					mch_id: config.storeNum,
					//生成的订单号
					out_trade_no: orderId,
					//设备信息
					device_info: 'WEB',
					//支付用户的ID
					openid: userId,
					//订单的内容
					body: '在' + storeData.storeName + '的消费账单',
					//订单的详细内容，为了满足要求先转换为json字符串
					detail: JSON.stringify({
						//物品清单
						goods_detail: goodsDetail
					}),
					total_fee: goodsTotalPrice,
					nonce_str: nonceStr,
					fee_type: 'CNY',
					spbill_create_ip: clientIP,
					time_start: orderStartTime,
					time_expire: orderEndTime,
					notify_url: config.payNotifyUrl,
					trade_type: 'JSAPI',
					sign_type: 'MD5'
				}
				//取出所有的对象key进行字典排序
				var dataKeys = Object.keys(requestOrderData);
				//判断是否无元素
				if(dataKeys.length == 0) {
					deferred.reject('-0087');
				}
				dataKeys = dataKeys.sort();
				//声明存放签名的字符串
				var signStr = '';
				//遍历对象key取回元素值
				for(var keyIndex in dataKeys) {
					//连接每个元素为查询字符串
					signStr += dataKeys[keyIndex] + '=' + requestOrderData[dataKeys[keyIndex]] + '&';
					//判断是否完成了遍历
					if(keyIndex == dataKeys.length - 1) {
						//最后将支付的key连接进去
						signStr += ('key=' + config.payKey);
						console.log(signStr);
						//对查询字符串进行md5加密
						util.md5(signStr).then(function(cryptStr) {
							console.log('签名字符串：', cryptStr);
							//设置调用统一接口的签名字符串
							requestOrderData.sign = cryptStr;
							//调用函数将下单数据转换为xml格式
							return orderData2xml(requestOrderData);
						}, function() {
							//加密字符串为md5字符串失败
							deferred.reject('-0086');
						}).then(function(xmlData) {
							console.log(xmlData);
							//定义用于拼接统一下单接口返回的数据的变量
							var data = '';
							//发送POST请求到统一下单接口
							var req = https.request({
								//指定接口地址域名
								hostname: 'api.mch.weixin.qq.com',
								//指定发送到的端口 443代表使用https
								port: 443,
								//指定接口地址的路径部分
								path: '/pay/unifiedorder',
								//指定发送的方法为POST
								method: 'POST',
								//设置发送的header
								headers: {
									//指定发送的数据类型为xml
									'Content-Type': 'application/xml;charset=utf-8'
								}
							}, function(res) {
								//监听接收返回数据函数
								res.on('data', function(chunk) {
									//拼接数据块
									data += chunk;
								});
								//监听接收返回数据完成函数
								res.on('end', function() {
									console.log(data);
									//数据接收完毕并转换为对象返回
									util.xml2obj(data).then(function(objData) {
										console.log(objData);
										objData = objData.xml;
										for(var key in objData) {
											objData[key] = objData[key][0];
										}
										console.log(objData);
										util.checkWxData(objData, config.payKey).then(function(result) {
											console.log('确定预支付消息来自微信服务器');
											console.log(result);
											if(result) {
												if(objData.return_code == 'SUCCESS' && objData.result_code == 'SUCCESS') {
													console.log(objData);
													deferred.resolve(objData);
												}
												else {
													console.log(objData.return_code, objData.result_code, objData.return_msg);
													deferred.reject('-0092');
												}
											}
											else {
												//数据不是来自微信服务器
												deferred.reject('-0014');
											}
										}, function() {
											//检查数据来源失败
											deferred.reject('-0094');
										});
									}, function() {
										deferred.reject('-0090');
									});
								});
							});
							//监听请求失败函数
							req.on('error', function(e) {
								console.log(e);
								//请求微信同意下单接口失败
								deferred.reject('-0089');
							});
							//写入请求的内容
							req.write(xmlData);
							//结束请求
							req.end();
						}, function() {
							//订单数据转换为xml数据失败
							deferred.reject('-0088');
						});
					}
				}
			}
		}
	}, function() {
		//生成随机字符串失败
		deferred.reject('-0069');
	});
	return deferred.promise;
}

//将下单数据转换成xml字符串函数
var orderData2xml = function(orderData) {
	var deferred = Q.defer();
	//尝试进行转换
	try {
		//定义存放xml字符串的变量
		var xmlStr = '<xml>\n';
		//遍历下单数据连接到xml字符串
		for(var key in orderData) {
			//如果是物品详情则需要使用CDATA标签保护json数据
			if(key == 'detail') {
				orderData[key] = '<![CDATA[' + orderData[key] + ']]>';
			}
			//连接xml字符串
			xmlStr += '<' + key + '>' + orderData[key] + '</' + key + ">\n";
		}
		//连接xml尾部结束标签
		xmlStr += '</xml>';
		//返回xml字符串
		deferred.resolve(xmlStr);
	}
	catch(e) {
		//转换失败
		deferred.reject();
	}
	return deferred.promise;
}

//暴露接口
module.exports = {
	index: index
}